﻿module SVM

let get_memory ((m,_,_,_,_) : float list * float list * int * bool * (int * int) list) index : float = List.nth m index
let get_reg ((_,r,_,_,_) : float list * float list * int * bool * (int * int) list) index : float =
  if index > 3 then
    failwith "Invalid register index"
  else
    List.nth r index

let set_value l value index =
  let rec tail_rec l value index acc =
    match index with
    | 0 -> acc @ [value] @ (l |> List.tail)
    | _ -> tail_rec (l |> List.tail) value (index - 1) (acc @ [l |> List.head])
  if index >= (l |> List.length) then
    failwith "List out of bound"
  else
    tail_rec l value index []

let dump (svm : float list * float list * int * bool * (int * int) list) : string =
  let (m,r,pc,e,_) = svm
  let rec print_memory (m : float list) (index : int) : string =
    match m with
    | [] -> ""
    | f :: fs ->
        if index % 10 = 0 && index <> 0 then
          "\n" + (string f) + "\t" + (print_memory fs (index + 1))
        else
          string f + "\t" + (print_memory fs (index + 1))

  let title = "**********DUMP*********\n"
  let memory_string = "MEMORY:\n" + (print_memory m 0) + "\n\n\n"
  let register_string = "REGISTERS: " + (r |> Seq.map(fun x -> string x) |> Seq.fold (fun x y -> x + " " + y) "") + "\n"
  title + memory_string + register_string + ("PROGRAM COUNTER: " + string pc)
  

